#include "MdPrompt.h"
#include <QDebug>
#include <QFile>
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>

MdPrompt *MdPrompt::instance = nullptr;

MdPrompt *MdPrompt::getInstance()
{
    if (instance == nullptr)
    {
        instance = new MdPrompt();
    }
    return instance;
}

MdPrompt::MdPrompt()
{
    qDebug() << "初始化MD翻译提示管理器";
    initDefaultPrompt();

    // 尝试从默认路径加载配置
    QString defaultPath = getPromptPath();
    if (!load(defaultPath))
    {
        qDebug() << "未能从默认路径加载配置，使用默认设置";
    }

    qDebug() << "已设置翻译提示信息";
}

QString MdPrompt::getPromptPath()
{
    return QCoreApplication::applicationDirPath() + "/md_prompt.json";
}

void MdPrompt::initDefaultPrompt()
{
    // 设置默认值
    m_promptInfo.prompt = R"(你是专业的技术文档翻译专家，精通中英双语。请将Markdown格式的技术文档从英文翻译成简体中文。

核心要求：
1. 完整翻译所有文本内容，不得省略或遗漏任何信息
2. 保持所有Markdown语法和文档结构完全不变
3. 生成符合中文表达习惯的流畅译文，避免生硬直译
4. 专业术语翻译准确且全文保持一致
5. 对于专业术语，首次出现时可在中文译名后保留英文原文，如：实时操作系统(RTOS)
6. 代码块内容保持原样，仅翻译注释
7. 保持链接URL、图片路径、表格结构和格式对齐方式不变
8. 使用中文标点符号，正确处理中英文混排的空格

特别注意：
- 完整翻译所有内容，不得省略任何信息
- 完整保留所有列表层级、脚注和引用
- 数学公式、HTML标记保持原样
- 技术词汇的翻译应符合行业通用译法，避免字面翻译导致的术语误用

直接输出翻译后的完整Markdown文档，无需解释翻译过程或添加额外内容。)";
    m_promptInfo.chatPrefix = "[待翻译内容开始]\n";
    m_promptInfo.chatSuffix =
        "\n[待翻译内容结束]\n\n请将上述Markdown文档翻译成地道流畅的中文，严格遵循以下原则：\n1. 完整翻译所有内容，不得省略任何信息\n2. 保持所有Markdown语法和格式不变\n3. 代码块内容保持原样，只翻译注释\n4. 保留所有URL、图片路径和引用标记\n5. 直接提供翻译结果，不要添加额外说明";

    // 设置默认的用户提示列表
    m_promptInfo.userPromptList = {
        R"(
## Memory requirements
To decode and display a GIF animation the following amount of RAM is required:
- `LV_COLOR_DEPTH 8`: 3 x image width x image height
- `LV_COLOR_DEPTH 16`: 4 x image width x image height
- `LV_COLOR_DEPTH 32`: 5 x image width x image height

## Example
```eval_rst
.. include:: ../../examples/libs/gif/index.rst
```

## API

```eval_rst
.. doxygenfile:: lv_gif.h
  :project: lvgl
```

## Technical Terms and Mixed Language Formatting

In embedded systems, Real-Time Operating Systems (RTOS) are critical for time-sensitive applications. Microcontrollers (MCUs) like ARM Cortex-M series or AVR ATmega chips form the core of many IoT devices. When developing firmware, concepts like Interrupt Service Routines (ISRs) and Direct Memory Access (DMA) are fundamental.

The SPI, I2C, and UART protocols enable communication between different hardware components. In power-constrained environments, implementing proper Power Management Units (PMUs) and sleep modes can significantly extend battery life.

For debugging embedded systems, JTAG and Serial Wire Debug (SWD) interfaces provide essential connectivity. Field-Programmable Gate Arrays (FPGAs) offer flexibility when standard MCUs cannot meet performance requirements.
)"
    };

    // 设置默认的助手提示列表
    m_promptInfo.assistantPromptList = {
        R"(
## 内存要求

为了解码和显示GIF动画，需要以下数量的RAM：
- `LV_COLOR_DEPTH 8`: 3 x 图像宽度 x 图像高度
- `LV_COLOR_DEPTH 16`: 4 x 图像宽度 x 图像高度
- `LV_COLOR_DEPTH 32`: 5 x 图像宽度 x 图像高度

## 示例

```eval_rst
.. include:: ../../examples/libs/gif/index.rst
```

## API

```eval_rst
.. doxygenfile:: lv_gif.h
  :project: lvgl
```

## 技术术语和混合语言格式

在嵌入式系统中，实时操作系统（Real-Time Operating Systems，RTOS）对时间敏感型应用至关重要。微控制器（Microcontrollers，MCUs）如 ARM Cortex-M 系列或 AVR ATmega 芯片构成了许多物联网（IoT）设备的核心。在开发固件时，中断服务例程（Interrupt Service Routines，ISRs）和直接内存访问（Direct Memory Access，DMA）等概念是基础知识。

SPI、I2C 和 UART 协议实现了不同硬件组件之间的通信。在功耗受限的环境中，实施适当的电源管理单元（Power Management Units，PMUs）和睡眠模式可以显著延长电池寿命。

对于嵌入式系统的调试，JTAG 和串行线调试（Serial Wire Debug，SWD）接口提供了必要的连接性。当标准微控制器无法满足性能需求时，现场可编程门阵列（Field-Programmable Gate Arrays，FPGAs）提供了灵活性。
)"
    };
}

MdPrompt::~MdPrompt() {}

bool MdPrompt::save(const QString &filePath)
{
    QJsonObject jsonObject;

    // 保存基本字段
    jsonObject["prompt"]     = m_promptInfo.prompt;
    jsonObject["chatPrefix"] = m_promptInfo.chatPrefix;
    jsonObject["chatSuffix"] = m_promptInfo.chatSuffix;

    // 保存用户提示列表
    QJsonArray userPrompts;
    for (const QString &prompt : m_promptInfo.userPromptList)
    {
        userPrompts.append(prompt);
    }
    jsonObject["userPrompts"] = userPrompts;

    // 保存助手提示列表
    QJsonArray assistantPrompts;
    for (const QString &prompt : m_promptInfo.assistantPromptList)
    {
        assistantPrompts.append(prompt);
    }
    jsonObject["assistantPrompts"] = assistantPrompts;

    // 写入文件
    QFile file(filePath);
    if (!file.open(QIODevice::WriteOnly))
    {
        qDebug() << "无法创建JSON文件:" << filePath;
        return false;
    }

    QJsonDocument jsonDoc(jsonObject);
    file.write(jsonDoc.toJson());
    file.close();

    qDebug() << "成功保存提示信息到文件:" << filePath;
    return true;
}

bool MdPrompt::load(const QString &filePath)
{
    QFile file(filePath);
    if (!file.open(QIODevice::ReadOnly))
    {
        qDebug() << "无法打开JSON文件:" << filePath;
        return false;
    }

    QByteArray jsonData = file.readAll();
    file.close();

    QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonData);
    if (jsonDoc.isNull())
    {
        qDebug() << "JSON文件格式无效:" << filePath;
        return false;
    }

    QJsonObject jsonObject = jsonDoc.object();

    // 读取基本字段
    if (jsonObject.contains("prompt"))
    {
        m_promptInfo.prompt = jsonObject["prompt"].toString();
    }
    if (jsonObject.contains("chatPrefix"))
    {
        m_promptInfo.chatPrefix = jsonObject["chatPrefix"].toString();
    }
    if (jsonObject.contains("chatSuffix"))
    {
        m_promptInfo.chatSuffix = jsonObject["chatSuffix"].toString();
    }

    // 读取用户提示列表
    m_promptInfo.userPromptList.clear();
    if (jsonObject.contains("userPrompts") && jsonObject["userPrompts"].isArray())
    {
        QJsonArray userPrompts = jsonObject["userPrompts"].toArray();
        for (const QJsonValue &value : userPrompts)
        {
            m_promptInfo.userPromptList.append(value.toString());
        }
    }

    // 读取助手提示列表
    m_promptInfo.assistantPromptList.clear();
    if (jsonObject.contains("assistantPrompts") && jsonObject["assistantPrompts"].isArray())
    {
        QJsonArray assistantPrompts = jsonObject["assistantPrompts"].toArray();
        for (const QJsonValue &value : assistantPrompts)
        {
            m_promptInfo.assistantPromptList.append(value.toString());
        }
    }

    qDebug() << "成功从文件加载提示信息:" << filePath;
    return true;
}

void MdPrompt::changePrompt(const QString &prompt, const QString &chatPrefix,
                            const QString &chatSuffix, const QVector<QString> &userPromptList,
                            const QVector<QString> &assistantPromptList)
{
    qDebug() << "修改提示信息";

    // 更新提示信息
    m_promptInfo.prompt              = prompt;
    m_promptInfo.chatPrefix          = chatPrefix;
    m_promptInfo.chatSuffix          = chatSuffix;
    m_promptInfo.userPromptList      = userPromptList;
    m_promptInfo.assistantPromptList = assistantPromptList;

    qDebug() << "提示信息已更新";
}

void MdPrompt::resetToDefault()
{
    qDebug() << "重置为默认提示信息";
    initDefaultPrompt();
    qDebug() << "已恢复默认提示信息";
}